package com.rjpacket.supernews.app.utils;

import android.content.Context;
import android.os.Environment;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by aaa on 15-3-11.
 */

/**
 * 图片缓存，根据网址生成文件名保存图片，同时根据文件名获取到图片
 */
public class FileCache {
    private static FileCache ourInstance;

    public static FileCache createInstance(Context context) {
        if (ourInstance == null) {
            ourInstance = new FileCache(context);
        }
        return ourInstance;
    }

    public static FileCache getInstance() {
        if (ourInstance == null) {
            throw new IllegalStateException("error");
        }
        return ourInstance;
    }

    private File fileCacheDir;

    /**
     * 初始化文件缓存
     *
     * @param context
     */
    private FileCache(Context context) {
        if (context != null) {
            //上下存在，直接获取缓存文件
            String state = Environment.getExternalStorageState();

            if (Environment.MEDIA_MOUNTED.equals(state)) {
                fileCacheDir = context.getExternalCacheDir();
            } else {
                fileCacheDir = context.getCacheDir();
            }
        } else {
            //上下文没有，用sd卡
            String state = Environment.getExternalStorageState();

            if (Environment.MEDIA_MOUNTED.equals(state)) {
                File directory = Environment.getExternalStorageDirectory();
                fileCacheDir = new File(directory, ".MySuperNews");
            } else {
                throw new IllegalArgumentException("error");
            }
        }

        if (fileCacheDir != null) {
            if (!fileCacheDir.exists()) {
                fileCacheDir.mkdirs();
            }
        } else {
            throw new IllegalArgumentException("error");
        }
    }

    /**
     * 根据网址将内容存入缓存文件夹
     *
     * @param url
     * @param data
     */
    public void putContent(String url, byte[] data) {
        if (url != null && data != null) {
            String fileName = mapUrlToFile(url);

            File targetFile = new File(fileCacheDir, fileName);

            boolean bok = true;

            if (!targetFile.exists()) {
                try {
                    bok = targetFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (bok) {
                FileOutputStream fout = null;
                try {
                    fout = new FileOutputStream(targetFile);

                    fout.write(data);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    StreamUtil.close(fout);
                }
            }
        }
    }

    /**
     * 同样根据图片网址获取到图片
     *
     * @param url
     * @return
     */
    public byte[] getContent(String url) {
        byte[] ret = null;

        if (url != null) {
            String fileName = mapUrlToFile(url);
            if (fileName.length() > 0) {
                File targetFile = new File(fileCacheDir, fileName);

                if (targetFile.exists()) {
                    FileInputStream fin = null;

                    try {
                        fin = new FileInputStream(targetFile);

                        ret = StreamUtil.readStream(fin);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        StreamUtil.close(fin);
                        fin = null;
                    }
                }
            }
        }

        return ret;
    }

    /**
     * 如何将图片的网址转化成文件名字
     *
     * @param url
     * @return
     */
    private String mapUrlToFile(String url) {
        String ret = null;

        if (url != null) {
            byte[] md5 = md5(url.getBytes());

            ret = hex(md5);
        }

        return ret;
    }

    /**
     * 将MD5生成的字节数组转化成16进制数，返回字符串
     *
     * @param data
     * @return
     */
    private String hex(byte[] data) {
        StringBuilder sb = new StringBuilder();

        if (data != null && data.length > 0) {
            for (byte b : data) {
                int h, l;

                h = (b >> 4) & 0x0f;
                l = b & 0x0f;

                sb.append(Integer.toHexString(h));
                sb.append(Integer.toHexString(l));
            }
        }

        return sb.toString();
    }

    /**
     * MD5消息摘要算法生成文件名的字节数组
     *
     * @param data
     * @return
     */
    private byte[] md5(byte[] data) {
        byte[] ret = null;

        if (data != null && data.length > 0) {
            try {
                MessageDigest digest = MessageDigest.getInstance("MD5");

                ret = digest.digest(data);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }

        return ret;
    }
}
